#include <string.h>
#include "gkt_debug.h"
#include "gkt_user.h"
#include "user_face_id.h"
#include "gkt_user_face_id.h"
#include "gkt_os.h"
#include "gkt_system.h"

#if defined(GKT_CONFIG_FACE_ID_ENABLE) && GKT_CONFIG_FACE_ID_ENABLE
#include "gkt_face_id.h"
#include "gkt_face_id_struct.h"

__RETMEM_USR user_face_id_info_s g_user_face_id_info;

void user_face_id_delete_item(uint32_t user_index)
{
	const user_face_id_item_s *c_item;
	s_msg_deluser_data deluser_data = {0};
	if(user_index < g_user_face_id.instance.item_available_nums){
		c_item = USER_FACE_ID_ITEM_C(user_index);
		deluser_data.user_id_heb = c_item->data[0];
		deluser_data.user_id_leb = c_item->data[1];
		gkt_face_id_send_command(MID_DELUSER,(uint8_t *)(&deluser_data),GKT_USER_FACE_ID_MAXSIZE);
		gkt_thread_sleep(200);//wait face_id complete
	}
}
#define user_face_id_reset_info	NULL
#define user_face_id_reset_partition	NULL

static int user_face_id_compare(const uint8_t *data_in,const uint8_t *data_local)
{
	uint16_t	index_in,index_local;
	index_in = (data_in[0]<<8) | data_in[1];
	index_local = (data_local[0]<<8) | data_local[1];
	gkt_info("index_in=%d,index_local=%d\n",index_in,index_local);
	if(index_in == index_local)
		return 1;
	else
		return 0;
}
#if defined(GKT_CONFIG_PALM_ENABLE) && GKT_CONFIG_PALM_ENABLE
extern int user_palm_verify(uint32_t *user_id, uint32_t excluded_user_index,
										uint32_t authority,const uint8_t *data, uint32_t length);
#endif
int user_face_id_verify(uint32_t *user_id, uint32_t excluded_user_index,
										uint32_t authority,const uint8_t *data, uint32_t length)
{
	const user_face_id_item_s *c_item;
	uint32_t item_index;
	int matched, retval;

	gkt_unused(excluded_user_index);
	item_index = 0;
	if (authority >= GKT_USER_AUTH_MAX) {
		while (item_index < g_user_face_id.instance.item_available_nums) {
			c_item = USER_FACE_ID_ITEM_C(item_index);
			if (USER_ITEM_IS_USED(&c_item->header)
				&& ((uint32_t)c_item->data_length <= length)) 
			{
				matched = user_face_id_compare(data, c_item->data);
				if (matched) {
					*user_id = GKT_USER_ID_BUILD(c_item->header.authority.type,
									0,
									GKT_USER_TYPE_FACE_ID, 
									c_item->header.user_index);
					return GKT_USER_VERIFY_PASSED;
				}
			}
			item_index++;
		}
	}
	else if (authority < GKT_USER_AUTH_TEMPORARY) {
		while (item_index < g_user_face_id.instance.item_available_nums) {
			c_item = USER_FACE_ID_ITEM_C(item_index);
			if (USER_ITEM_IS_USED(&c_item->header)
				&& ((uint32_t)c_item->header.authority.type == authority)
				&& ((uint32_t)c_item->data_length <= length)) 
			{
				matched = user_face_id_compare(data, c_item->data);
				if (matched) {
					*user_id = GKT_USER_ID_BUILD(c_item->header.authority.type,
									0,
									GKT_USER_TYPE_FACE_ID, 
									c_item->header.user_index);
					return GKT_USER_VERIFY_PASSED;
				}
			}
			item_index++;
		}	
	}


	retval = GKT_USER_VERIFY_FAILED;
	return retval;
}
#define user_face_id_verify_update	NULL
#define user_face_id_verify_finalize	NULL
#define user_face_id_enroll_init	NULL
static int user_face_id_enroll_run(const uint8_t *data, 
					uint32_t length)
{
	uint32_t i;
	gkt_unused(g_user_face_id_info);

	for (i = 0; i < length; i++)
		g_user_face_id.enroll_item.data[i] = data[i];

	g_user_face_id.enroll_item.data_length = (uint8_t)length;
	return GKT_USER_ENROLL_COMPLETE;
}
#define user_face_id_enroll_uninit	NULL

#define user_face_id_config	NULL
#define user_face_id_add_item	NULL
//#define user_face_id_init	NULL

extern user_face_id_s g_user_palm;
void user_face_id_sync(int32_t timeout)
{
	int timeout_ready,result;	
	uint8_t face_id_data[128]={0},cnt,i;
	uint8_t *id_data;
	uint32_t retval,user_id;

	retval = GKT_EPARAM;
	timeout_ready = timeout;
	gkt_face_id_send_command(MID_GET_ALL_USERID,NULL,0);
	do{
		gkt_thread_sleep(20);
		timeout_ready -= 20;
		if (timeout_ready < 0){
			break;
		}
		retval = gkt_face_id_get_command_data(MID_GET_ALL_USERID,face_id_data);
		if(retval == GKT_SUCCESS)
			break;
	}while(1);
	if((retval == GKT_SUCCESS) && (face_id_data != NULL)){
		if(face_id_data[0] == MID_GET_ALL_USERID){
			cnt = face_id_data[2];
			for (i=0; i<cnt; i++) {
				id_data = (face_id_data+3+2*i);
				user_reload_items_v(&g_user_face_id.instance);
				result = user_face_id_verify(&user_id,0,GKT_USER_AUTH_MAX,id_data,2);
				if (result != GKT_USER_VERIFY_PASSED)
				{
#if defined(GKT_CONFIG_PALM_ENABLE) && GKT_CONFIG_PALM_ENABLE
					user_reload_items_v(&g_user_palm.instance);
					result = user_palm_verify(&user_id,0,GKT_USER_AUTH_MAX,id_data,2);
					if (result != GKT_USER_VERIFY_PASSED)
#endif
					{
						gkt_face_id_send_command(MID_DELUSER,id_data,GKT_USER_FACE_ID_MAXSIZE);
						gkt_thread_sleep(200);//wait face_id complete
					}
				}
			}
		}
	}
}

int user_face_id_init(void)
{
	if (GKT_SYSTEM_RESET_WAKEUP != g_system_info.reset_mode){

	}
	return GKT_SUCCESS;
}

USER_TYPE_OPS_DEFINE(face_id);
user_face_id_s g_user_face_id = {
	.instance = {
		.type = GKT_USER_TYPE_FACE_ID,
		.flags = 0,
		.c_ops = USER_TYPE_OPS_PTR(face_id),
		.c_partition_name = "UserFaceId",

		.info = &g_user_face_id_info.common,

		.auth_user_maxnums = {
			GKT_USER_FACE_ID_ADMIN_MAXNUMS,
			GKT_USER_FACE_ID_NORMAL_MAXNUMS,
			GKT_USER_FACE_ID_GUEST_MAXNUMS,
		},

		.item_size = USER_FACE_ID_ITEM_SIZE,
		.item_data_maxsize = 0,
		.item_header = &g_user_face_id.enroll_item.header,
	},
};

#endif

